using System;
using System.Text;
using System.Security.Cryptography;
using System.Globalization;

namespace Antix.Security
{
	/// <summary>
	/// RSA Encryption rountines
	/// </summary>
	public class Crypto
	{
		private CspParameters _Params;
		private RSACryptoServiceProvider _RSA;

        #region Hash

        /// <summary>
        /// Hash a value
        /// </summary>
        public static string Hash(string value)
        {
            return Hash(value, false);
        }

        /// <summary>
        /// Hash a value
        /// </summary>
        public static string Hash(string value, bool base64Encode)
        {
            MD5CryptoServiceProvider service = new MD5CryptoServiceProvider();
            byte[] bytes = service.ComputeHash(Encoding.Default.GetBytes(value));

            if (base64Encode) { return Convert.ToBase64String(bytes); }
            else { return Encoding.Default.GetString(bytes); }
        }

        #endregion

        #region Encrypt

		/// <summary>
		/// Encrypt a string using RSA encryption.
		/// </summary>
		/// <param name="value">String to encrypt</param>
		/// <param name="publicKey">Public Key</param>
		/// <returns>Encrypted Value</returns>
		public string Encrypt( string value, string publicKey )
		{

			try
			{
				_RSA.FromXmlString( publicKey );
				return Encoding.Default.GetString( _RSA.Encrypt( Encoding.Default.GetBytes( value ), false ) );
				//encrypt = Convert.ToBase64String(mobjRSA.Encrypt( Encoding.Default.GetBytes(value), False))
			}
			catch( Exception ex )
			{
				throw ex;
			}
		}

		#endregion

		#region Decrypt

		/// <summary>
		/// Decrypt a string encrypted using RSA encryption
		/// </summary>
		/// <param name="value">Encrypted string</param>
		/// <param name="privateKey">Private key</param>
		/// <param name="ignoreBadData">Suppresses exception thrown on encountering Bad Data</param>
		/// <returns></returns>
		public string Decrypt( string value, string privateKey, bool ignoreBadData )
		{
			try
			{
				_RSA.FromXmlString( privateKey );
				if( value.Length > 0 )
				{
					// decrypt = Encoding.Default.GetString(mobjRSA.Decrypt(Convert.FromBase64String(value), False))
					return Encoding.Default.GetString( _RSA.Decrypt( Encoding.Default.GetBytes( value ), false ) );
				}

				return "";
			}
			catch( CryptographicException ex )
			{
				if( ignoreBadData )
				{

					return value;
				}
				else
				{
					throw ex;
				}
			}
		}

		#endregion
		
		#region Constructor

		/// <summary>
		/// RSA encryption routines
		/// </summary>
		public Crypto()
		{

			try
			{
				_Params = new CspParameters();
				_Params.Flags = CspProviderFlags.UseMachineKeyStore;
				_RSA = new RSACryptoServiceProvider( _Params );

			}
			catch ( Exception ex )
			{
				throw ex;
			}
		}

		#endregion 

	}
}